package com.borball.store.comp;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.TableRowSorter;

import com.borball.store.domain.User;
import com.borball.store.util.UserUtils;

import craky.component.CommonTableModel;
import craky.componentc.JCButton;
import craky.componentc.JCLabel;
import craky.componentc.JCMessageBox;
import craky.componentc.JCPopupMenu;
import craky.componentc.JCScrollTable;
import craky.componentc.JCTable;
import craky.componentc.JCTableHeader;
import craky.componentc.JCTextField;
import craky.keeper.EmptyComponent;
import craky.keeper.KeeperApp;
import craky.keeper.KeeperPane;
import craky.keeper.util.KeeperUtil;
import craky.layout.LineLayout;
import craky.util.IOUtil;

public class UserManagementPane extends KeeperPane {

	private static final long serialVersionUID = 2583431180094797757L;

	private static final String CMD_INSERT = "Insert";

	private static final String CMD_MODIFY = "Modify";

	private static final String[] COLUMNS_NAME = { "姓名", "省份证", "联系方式" };

	protected KeeperApp keeper;

	protected User currentUser;

	protected CommonTableModel<User> model;

	protected List<User> data;

	protected User currentData;

	protected Action insertAction, modifyAction, deleteAction, submitAction, cancelAction;

	protected JCTable table;

	protected JCPopupMenu popup;

	protected JComponent bottom, center;

//	protected JComponent ecFName, ecFCardId, ecFMobile;

	protected JComponent ecName, ecCardId, ecMobile;

	protected JCTextField cpName, cpCardId, cpMobile;

	private JCButton btnModify, btnDelete, btnInsert, btnSubmit, btnCancel;

//	private boolean showFind;

	private boolean modifying;

	private int selectedIndex;

	public UserManagementPane(KeeperApp keeper) {
		this.keeper = keeper;
		this.currentUser = keeper.getCurrentUser();

		this.selectedIndex = -1;

		load();
		initActions();
		initUI();
		resetTypes();
	}

	private void initActions() {
		insertAction = new AbstractAction("\u6DFB\u52A0") {
			private static final long serialVersionUID = 5056698643009336063L;

			public void actionPerformed(ActionEvent e) {
				insertOrModify(true);
			}
		};

		modifyAction = new AbstractAction("\u4FEE\u6539") {
			private static final long serialVersionUID = 8222836515926767063L;

			public void actionPerformed(ActionEvent e) {
				insertOrModify(false);
			}
		};

		deleteAction = new AbstractAction("\u5220\u9664") {
			private static final long serialVersionUID = -4608405524916997614L;

			public void actionPerformed(ActionEvent e) {
				delete();
			}
		};

		submitAction = new AbstractAction("\u786E\u5B9A") {
			private static final long serialVersionUID = 6989199497316998154L;

			public void actionPerformed(ActionEvent e) {
				submit();
			}
		};

		cancelAction = new AbstractAction("\u53D6\u6D88") {
			private static final long serialVersionUID = 6989199497316998154L;

			public void actionPerformed(ActionEvent e) {
				cancel();
			}
		};

		modifyAction.setEnabled(false);
		deleteAction.setEnabled(false);
	}

	private void initUI() {
		btnModify = new JCButton(modifyAction);
		btnDelete = new JCButton(deleteAction);
		btnInsert = new JCButton(insertAction);
		btnSubmit = new JCButton(submitAction);
		btnCancel = new JCButton(cancelAction);
		btnModify.setPreferredSize(new Dimension(-1, 21));
		btnDelete.setPreferredSize(btnModify.getPreferredSize());
		btnInsert.setPreferredSize(btnModify.getPreferredSize());
		btnSubmit.setPreferredSize(btnModify.getPreferredSize());
		btnCancel.setPreferredSize(btnModify.getPreferredSize());
		btnSubmit.setVisible(false);
		btnCancel.setVisible(false);
		EmptyComponent centerParent = new EmptyComponent();
		setLayout(new BorderLayout());
		centerParent.setLayout(new BorderLayout(0, 3));
		createCenter();
//		createTop();
		createBottom();

		this.add(centerParent, BorderLayout.CENTER);

		if (center != null) {
			centerParent.add(center, BorderLayout.CENTER);
		}

//		if (top != null) {
//			centerParent.add(top, BorderLayout.NORTH);
//		}

		if (bottom != null) {
			centerParent.add(bottom, BorderLayout.SOUTH);
		}

	}

	protected void resetTypes() {

	}

	public void load() {
		data = UserUtils.getInstance().getAllUsers();
	}
	
	public void reload(){
		load();
		model.refreshUI();
	}

//	protected JComponent createTop() {
//		top = new EmptyComponent();
//		EmptyComponent ecFind = new EmptyComponent();
//
//		JCButton btnFind = new JCButton("\u67E5\u627E");
//		Border border1 = new EmptyBorder(3, 0, 0, 3);
//		Border border2 = new EmptyBorder(3, 0, 0, 0);
//		JComponent ecButton = createTitledComponent(null, btnFind, new EmptyBorder(5, 0, 2, 2), 0);
//		JCLabel lbName = new JCLabel("姓名");
//		JCLabel lbCardid = new JCLabel("省份证");
//		JCLabel lbMobile = new JCLabel("联系方式");
//
//		ecFName = new JCTextField();
//		ecFCardId = new JCTextField();
//		ecFMobile = new JCTextField();
//
//		btnFind.addActionListener(new ActionListener() {
//			public void actionPerformed(ActionEvent e) {
//				load();
//			}
//		});
//		
//		btnFind.setFocusable(false);
//		btnFind.setIconTextGap(0);
//		btnFind.setIcon(KeeperUtil.getIcon("find.png"));
//		btnFind.setImage(KeeperUtil.getImage("common_button_normal_bg.png", true));
//		btnFind.setRolloverImage(KeeperUtil.getImage("common_button_rollover_bg.png", true));
//		btnFind.setPressedImage(KeeperUtil.getImage("common_button_pressed_bg", true));
//		ecFind.setLayout(new BoxLayout(ecFind, BoxLayout.X_AXIS));
//		ecButton.setPreferredSize(new Dimension(57, -1));
//
//		top.setPreferredSize(new Dimension(-1, 27));
//		top.setLayout(new BorderLayout());
//
//		ecFName.setPreferredSize(new Dimension(45, -1));
//		ecFCardId.setPreferredSize(new Dimension(240, -1));
//		ecFMobile.setPreferredSize(new Dimension(150, -1));
//
//		ecFind.add(ecFName = createTitledComponent(lbName, ecFName, border1, 0));
//		ecFind.add(ecFCardId = createTitledComponent(lbCardid, ecFCardId, border1, 0));
//		ecFind.add(ecFMobile = createTitledComponent(lbMobile, ecFMobile, border2, 0));
//
//		top.add(ecFind, BorderLayout.CENTER);
//		top.add(ecButton, BorderLayout.EAST);
//		return top;
//	}

	protected JComponent createBottom() {

		bottom = new EmptyComponent();
		bottom.setBorder(new CompoundBorder(new EmptyBorder(0, 0, 0, 0), new LineBorder(new Color(84, 165, 213))));
		bottom.setPreferredSize(new Dimension(-1, 77));
		bottom.setLayout(new BorderLayout());
		bottom.add(createDetailComponent(), BorderLayout.CENTER);

		EmptyComponent buttonContainer = new EmptyComponent();
		buttonContainer.setLayout(new LineLayout(3, 0, 5, 0, 3, LineLayout.TRAILING, LineLayout.TRAILING,
				LineLayout.VERTICAL));
		buttonContainer.setPreferredSize(new Dimension(85, -1));
		buttonContainer.add(btnSubmit, LineLayout.END_FILL);

		buttonContainer.add(btnDelete, LineLayout.END_FILL);
		buttonContainer.add(btnModify, LineLayout.END_FILL);

		buttonContainer.add(btnInsert, LineLayout.END_FILL);
		buttonContainer.add(btnCancel, LineLayout.END_FILL);
		bottom.add(buttonContainer, BorderLayout.EAST);

		return bottom;
	}

	protected JComponent createCenter() {
		final Class<?>[] columnsClass = { String.class, String.class, String.class };
		final String[] getMethodsName = { "getName", "getCardid", "getMobile" };
		final String[] setMethodsName = { "setName", "setCardid", "setMobile" };
		final int[] columnsPreferredWidth = { 70, 220, 150 };
		EmptyComponent ec = new EmptyComponent();
		JCScrollTable scTable = new JCScrollTable();
		table = scTable.getTable();
		model = new CommonTableModel<User>(table, COLUMNS_NAME, columnsClass, getMethodsName, setMethodsName, data);
		TableRowSorter<CommonTableModel<User>> sorter = new TableRowSorter<CommonTableModel<User>>(model);

		scTable.setAlpha(0.0f);
		scTable.setColumnControlEnabled(false);
		ec.setLayout(new BorderLayout());
		ec.add(scTable, BorderLayout.CENTER);
		table.setModel(model);
		table.setDragEnabled(false);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setRowSorter(sorter);
		table.setRendererOpaque(false);
		((JCTableHeader) table.getTableHeader()).setShowPopupMenu(false);
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				whenSelectionChanged(e);
			}
		});
		table.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				select(e);
			}

			public void mouseReleased(MouseEvent e) {
				showPopupMenu(e);
			}
		});

		for (int i = 0; i < columnsPreferredWidth.length; i++) {
			table.getColumnModel().getColumn(i).setPreferredWidth(columnsPreferredWidth[i]);
		}

		return center = ec;
	}

	private JComponent createDetailComponent() {
		EmptyComponent ec = new EmptyComponent();
		EmptyComponent firstRow = new EmptyComponent();

		JCLabel lbName = new JCLabel("姓名");
		JCLabel lbCardid = new JCLabel("省份证");
		JCLabel lbMobile = new JCLabel("联系方式");

		Border border = new EmptyBorder(0, 0, 0, 5);
		cpName = new JCTextField();
		cpCardId = new JCTextField();
		cpMobile = new JCTextField();

		firstRow.setLayout(new BoxLayout(firstRow, BoxLayout.X_AXIS));
		firstRow.setPreferredSize(new Dimension(-1, 25));
		firstRow.setPreferredSize(new Dimension(-1, 24));

		firstRow.add(ecName = createTitledComponent(lbName, cpName, border, 3));
		firstRow.add(ecCardId = createTitledComponent(lbCardid, cpCardId, border, 3));
		firstRow.add(ecMobile = createTitledComponent(lbMobile, cpMobile, border, 3));

		ec.setLayout(new BorderLayout(0, 5));
		ec.setBorder(new EmptyBorder(3, 5, 2, 2));
		ec.add(firstRow, BorderLayout.NORTH);

		ecName.setPreferredSize(new Dimension(80, -1));
		ecCardId.setPreferredSize(new Dimension(250, -1));
		ecMobile.setPreferredSize(new Dimension(150, -1));

		resetTextStatus(false);
		
		return ec;
	}

	private JComponent createTitledComponent(JComponent titleComponent, JComponent component, Border border, int hgap) {
		EmptyComponent ec = new EmptyComponent();
		ec.setBorder(border);
		ec.setLayout(new BorderLayout(hgap, 0));
		ec.add(component, BorderLayout.CENTER);

		if (titleComponent != null) {
			ec.add(titleComponent, BorderLayout.WEST);
		}

		return ec;
	}

	private void resetDetailValues() {
		if (bottom.isVisible()) {
			if (currentData == null) {
				clearValues();
			} else {
				fillValues();
			}

			resetTextStatus(false);
			resetButtonStatus(false);
		}
	}

	private void clearValues() {
		 cpName.setText(null);
		 cpCardId.setText(null);
		 cpMobile.setText(null);
	}

	private void fillValues() {
		cpName.setText(currentData.getName());
		cpCardId.setText(currentData.getCardid());
		cpMobile.setText(currentData.getMobile());

	}

	private void resetTextStatus(boolean editable) {
		 cpName.setEditable(editable);
		 cpCardId.setEditable(editable);
		 cpMobile.setEditable(editable);
	}

	private void resetButtonStatus(boolean modifying) {
		this.modifying = modifying;
		btnSubmit.setVisible(modifying);
		btnCancel.setVisible(modifying);
		btnInsert.setVisible(!modifying);
		btnModify.setVisible(!modifying);
		btnDelete.setVisible(!modifying);
	}

	private void select(MouseEvent e) {
		int row = table.rowAtPoint(e.getPoint());

		if (row >= 0 && SwingUtilities.isRightMouseButton(e)) {
			table.getSelectionModel().setSelectionInterval(row, row);
		} else if (row < 0 && !SwingUtilities.isMiddleMouseButton(e)) {
			if (selectedIndex >= 0) {
				table.clearSelection();
			} else {
				resetDetailValues();
			}
		}
	}

	private void showPopupMenu(MouseEvent e) {
		if (popup != null && SwingUtilities.isRightMouseButton(e)) {
			popup.show((Component) e.getSource(), e.getX(), e.getY());
		}
	}

	private void whenSelectionChanged(ListSelectionEvent e) {
		currentData = table.getSelectedRow() < 0 ? null : model.getSelectedRowData();
		boolean selectedEmpty = (selectedIndex = table.getSelectedRow()) < 0;
		modifyAction.setEnabled(!selectedEmpty);
		deleteAction.setEnabled(!selectedEmpty);
		resetDetailValues();
	}

	protected void resetRowValues(User user) {
		user.setName(cpName.getText());
		user.setCardid(cpCardId.getText());
		user.setMobile(cpMobile.getText());
	}

	public void cancel() {
		btnSubmit.setActionCommand(null);
		resetDetailValues();
	}

	protected boolean checkInput() {
		return true;
	}

	protected boolean checkFilter(User data) {
		return true;
	}

	public void submit() {
		if (!btnSubmit.isVisible() || !checkInput()) {
			return;
		}

		if(checkNull()){
			String cmd = btnSubmit.getActionCommand();
			boolean insert = true;
			User user = null; 
			
			if (CMD_INSERT.equals(cmd)) {
				user = new User();
				user.setName(cpName.getText().trim());
				user.setCardid(cpCardId.getText().trim());
				user.setMobile(cpMobile.getText().trim());
				
			} else if (CMD_MODIFY.equals(cmd)) {
				user = currentData;
				insert = false;
			}

			resetRowValues(user);

			if (insert) {
				if(checkExisting()){
					UserUtils.getInstance().addUser(user);
					
					model.insertRowData(user);
					int row = model.convertRowIndexesToView(model.getRowCount() - 1)[0];
					table.getSelectionModel().setSelectionInterval(row, row);
				}

			} else {
				UserUtils.getInstance().updateUser(user);
				
				model.refreshRowOnView(selectedIndex);
				fillValues();
			}

			resetButtonStatus(false);
			resetTextStatus(false);
			btnSubmit.setActionCommand(null);
		}

	}

	private boolean checkNull() {
		if ("".equals(cpName.getText())) {
			JCMessageBox.createErrorMessageBox(keeper.getMainFrame(), "必填项为空", "请输入所有必填项").open();

			cpName.requestFocus();
			return false;
		}

		return true;
	}

	private boolean checkExisting(){
		if(isExisting()){
			JCMessageBox.createErrorMessageBox(keeper.getMainFrame(), "用户已存在", "该用户已存在").open();

			cpName.requestFocus();
			return false;
		}
		return true;
	}
	
	private boolean isExisting() {
		return UserUtils.getInstance().isExisting(cpName.getText().trim());
	}

	public void insertOrModify(boolean insert) {
		if (modifying) {
			cancel();
		}

		btnSubmit.setActionCommand(insert ? CMD_INSERT : CMD_MODIFY);
		resetTextStatus(true);
		resetButtonStatus(true);

		if (insert) {
			clearValues();
			cpName.requestFocus();
		} else {
			cpName.setEditable(false);
		}
	}

	public void delete() {
		String message = "\u786E\u5B9A\u8981\u5220\u9664\u8BE5\u8BB0\u5F55\u5417\uFF1F";
		JCMessageBox box = JCMessageBox.createQuestionMessageBox(keeper.getMainFrame(), "\u5220\u9664", message);

		if (box.open() == JCMessageBox.YES_OPTION) {
			UserUtils.getInstance().deleteUser(currentData);
			model.delRowOnViewAt(selectedIndex);
		}
	}

	public List<User> getAllData() {
		return data;
	}

	public void exportToCSV() {
		final String DOT_CSV = ".csv";
		JFileChooser chooser = new JFileChooser();
		String filterDes = "CSV (\u9017\u53F7\u5206\u9694)(*.csv)";
		FileNameExtensionFilter filter = new FileNameExtensionFilter(filterDes, "csv");
		chooser.setFileFilter(filter);
		int ret = chooser.showSaveDialog(keeper.getMainFrame());

		if (ret != JFileChooser.APPROVE_OPTION) {
			return;
		}

		File file = chooser.getSelectedFile();
		String path = file.getAbsolutePath();
		String info = null;

		if (!path.toLowerCase().endsWith(DOT_CSV)) {
			file = new File(path += DOT_CSV);
		}

		try {
			final String LINE_SEP = "\r\n";
			IOUtil.writeToFile(file, Arrays.toString(COLUMNS_NAME).replaceAll("\\[|\\]| ", "") + LINE_SEP, null, false);

			for (User pay : data) {
				IOUtil.writeToFile(file, pay.toString() + LINE_SEP, null, true);
			}

			info = "<html>\u6210\u529F\u5BFC\u51FA\u5230\u6587\u4EF6\uFF1A<br>" + path;
		} catch (IOException e) {
			info = "<html>\u5BFC\u51FA\u65F6\u53D1\u751F\u5F02\u5E38\uFF0C\u8BF7\u68C0\u67E5\u662F\u5426\u5B58\u5728\u4EE5\u4E0B"
					+ "\u540C\u540D\u6587\u4EF6\u5939\u6216\u540C\u540D\u53EA\u8BFB\u6587\u4EF6\uFF01<br>" + path;
		} finally {
			if (info != null) {
				JCMessageBox.createInformationMessageBox(keeper.getMainFrame(), "\u5BFC\u51FA", info).open();
			}
		}
	}

	@Override
	public String getType() {
		return "用户管理";
	};
	

	@Override
	public void refresh() {
		load();
		this.center.repaint();
	}

}
